package org.dennisit.elastic.process;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;

import org.apache.log4j.spi.ErrorCode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.WildcardQuery;
import org.dennisit.elastic.pojo.Time;
import org.dennisit.elastic.pojo.User;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.FuzzyLikeThisFieldQueryBuilder;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;

import com.alibaba.fastjson.JSON;

public class ESClient {
	private Client client;

	public void init() {
		client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300));
	}

	public void close() {
		client.close();
	}

	/**
	 * 新增数据
	 */
	public void createIndex() {
		for (int i = 0; i < 1000; i++) {
			User user = new User();
			user.setId(new Long(i));
			user.setName("huang fox " + i);
			user.setAge(i % 100);
			client.prepareIndex("users", "user").setSource(generateJson(user))
					.execute().actionGet();
		}
	}

	/**
	 * 转换成json对象
	 * 
	 * @param user
	 * @return
	 */
	public String generateJson(User user) {
		String json = "";
		try {
			XContentBuilder contentBuilder = XContentFactory.jsonBuilder()
					.startObject();
			contentBuilder.field("id", user.getId() + "");
			contentBuilder.field("name", user.getName());
			contentBuilder.field("age", user.getAge() + "");

			json = contentBuilder.endObject().string();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}

	/**
	 * 添加时间类型字段
	 */
	public void addTime() {
		Time time = new Time();
		// Date nowTime=new Date();
		// SimpleDateFormat t=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// time.setTime(t.format(nowTime));
		// client.prepareIndex("time", "times").setSource(toJson(time))
		// .execute().actionGet();

		// time.setTime("2016.10.10");
		// client.prepareIndex("time", "times2").setSource(toJson(time))
		// .execute().actionGet();

		// time.setTime("2016年10月10日");
		// client.prepareIndex("time", "times3").setSource(toJson(time))
		// .execute().actionGet();

		// time.setTime("2016/10/10");
		// client.prepareIndex("time", "times4").setSource(toJson(time))
		// .execute().actionGet();

		time.setTime("2016-10-10");
		client.prepareIndex("time", "times5").setSource(toJson(time)).execute()
				.actionGet();
		System.out.println("新增成功");
	}

	public String toJson(Time time) {
		String json = "";
		try {
			XContentBuilder contentBuilder = XContentFactory.jsonBuilder()
					.startObject();
			contentBuilder.field("time", time.getTime() + "");

			json = contentBuilder.endObject().string();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}

	public void searchTime() {
		// SearchResponse response = client.prepareSearch("time")
		// .setTypes("times").execute().actionGet();
		// SearchResponse response = client.prepareSearch("time")
		// .setTypes("times2").execute().actionGet();
		// SearchResponse response = client.prepareSearch("time")
		// .setTypes("times3").execute().actionGet();
		SearchResponse response = client.prepareSearch("time")
				.setTypes("times4").execute().actionGet();
		// SearchResponse response = client.prepareSearch("time")
		// .setTypes("times5").execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 删除指定id的索引
	 * 
	 * @param id
	 */
	public void deleteIndex(String id) {
		DeleteResponse response = client.prepareDelete("users", "user", id)
				.execute().actionGet();
		System.out.println(response.getId());
	}

	/**
	 * 更新对应id 的索引数据
	 * 
	 * @param indexname
	 *            索引库名
	 * @param type
	 *            索引类型
	 * @param jsondatajson格式的数据
	 *            （待更新数据）
	 * @param id
	 *            索引对象单独指定ID
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */

	public void updateIndex(String indexname, String type, String jsondata,
			String id) throws InterruptedException, ExecutionException {

		UpdateRequest updateRequest = new UpdateRequest();
		updateRequest.index(indexname);
		updateRequest.type(type);
		updateRequest.id(id);
		updateRequest.doc(jsondata);
		// updateRequest.upsert(indexRequest);//若id不存在，更新插入操作
		UpdateResponse response = client.update(updateRequest).get();
		long _version = response.getVersion();
		// Returns true if document was created due to an UPSERT operation
		boolean created = response.isCreated();
		if (created) {
			System.out.println("UPSERT operation，已更新索引至第" + _version + "版本："
					+ indexname + ":-<<:" + type + ":-<<:" + id + ":-<<:"
					+ jsondata);
		} else {
			System.out.println("已更新索引至第" + _version + "版本：" + indexname
					+ ":-<<:" + type + ":-<<:" + id + ":-<<:" + jsondata);
		}
	}

	/**
	 * 搜索 ---精确
	 */
	public void search() {
		SearchResponse response = client.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.termQuery("id", "88")).setFrom(0)
				.setSize(60).setExplain(true).execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 搜索 ---范围
	 */
	public void search2() {
		SearchResponse response = client
				.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setPostFilter(
						FilterBuilders.rangeFilter("age").from(20).to(30))
				.setFrom(0).setSize(60).setExplain(true).execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 搜索 ---模糊
	 */
	public void search3() {
		SearchResponse response = client
				.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(
						new FuzzyLikeThisFieldQueryBuilder("name")
								.likeText("张")).setFrom(0).setSize(60)
				.setExplain(true).execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 搜索 ---短语
	 */
	public void search4() {
		SearchResponse response = client
				.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.matchPhraseQuery("name", "huang fox 0"))
				.setFrom(0).setSize(60).setExplain(true).execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 搜索 ---模糊2
	 */
	public void search5() {
		SearchResponse response = client.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.wildcardQuery("id", "*8*")).setFrom(0)
				.setSize(60).setExplain(true).execute().actionGet();

		SearchHits hits = response.getHits();// 获取结果记录
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

	/**
	 * 他能够过id、index、type查询某个索引
	 * 
	 * @param id
	 * @return
	 */
	public User getIndexById(String id) {
		User user = new User();
		GetResponse response = client.prepareGet("users", "user", id).execute()
				.actionGet();
		Map<String, Object> rpmap = response.getSource();
		// String json = JSON.toJSONString(response.getSource());// map对象转成json
		if (rpmap == null) {
			System.out.println("Empty.");
			return null;
		}
		Iterator<Entry<String, Object>> iterator = rpmap.entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<String, Object> ent = iterator.next();
			System.out.println(ent.getKey() + " " + ent.getValue());
		}
		return user;
	}

	/**
	 * 分頁查詢，返回搜索結果SearchResponse
	 * 
	 * @param queryBuilder
	 *            查詢條件
	 * @param indexname
	 *            索引库名 相當於 数据库名
	 * @param type
	 *            索引类型 相當於 表名
	 * @param sort
	 *            排序字段
	 * @param order
	 *            排序方式
	 * @param page
	 *            当前页码
	 * @param pageSize
	 *            分页大小
	 * @return 返回搜索結果SearchResponse
	 */

	public SearchResponse searcher(String sort, String order, Integer page,
			Integer pageSize) {

		try {
			// 创建查询索引
			SearchRequestBuilder searchRequestBuilder = client
					.prepareSearch("users");
			// 设置查询索引类型
			searchRequestBuilder.setTypes("user");
			// 设置查询条件
			TermQueryBuilder a = QueryBuilders.termQuery("name", "fox");
			searchRequestBuilder.setQuery(a);
			// 分頁
			if ((page > 0) && (pageSize > 0)) {

				// 设置查询数据的位置,分页用吧
				searchRequestBuilder.setFrom(pageSize * (page - 1));
				// 设置查询结果集的最大条数
				searchRequestBuilder.setSize(pageSize);

			}

			// 字段排序
			SortOrder sortOrder = SortOrder.ASC;// 排序方式 默认升序
			// 排序方式
			if (order.equals("desc")) {
				sortOrder = SortOrder.DESC;// 排序方式 註明降序
			}

			// 排序字段
			if ((null != sort) && (!sort.equals(""))) {
				searchRequestBuilder.addSort(sort, sortOrder);// 升序
			}

			// 设置是否按查询匹配度排序
			searchRequestBuilder.setExplain(true);
			// 最后就是返回搜索响应信息
			SearchResponse response = searchRequestBuilder.execute()
					.actionGet();

			return response;

		} catch (Exception e) {

			e.printStackTrace();
			return null;
		}

	}

	/**
	 * 根据条件 统计个数
	 * 
	 * @param queryBuilder
	 *            查詢條件
	 * @param indexname索引库名
	 *            相當於 数据库名
	 * @param type索引类型
	 *            相當於 表名
	 * @return
	 */

	public long countQuery() {
		// 设置查询条件
		TermQueryBuilder a = QueryBuilders.termQuery("name", "fox");
		CountResponse response = client.prepareCount("users").setTypes("user")
				.setQuery(a).execute().actionGet();

		return response.getCount();

	}
}
